/******************************************************************************
*  A Teaching GA					  Developed by Hal Stringer & Annie Wu, UCF
*  Version 2, January 18, 2004
*******************************************************************************/

import java.io.*;
import java.util.*;
import java.text.*;

public class FitnessIPD extends FitnessFunction{

/*******************************************************************************
*                            INSTANCE VARIABLES                                *
*******************************************************************************/


/*******************************************************************************
*                            STATIC VARIABLES                                  *
*******************************************************************************/


/*******************************************************************************
*                              CONSTRUCTORS                                    *
*******************************************************************************/

	public FitnessIPD(){
		name = "Prisoner's Dilemma Problem";
	}

/*******************************************************************************
*                                MEMBER METHODS                                *
*******************************************************************************/

//  COMPUTE A CHROMOSOME'S RAW FITNESS *************************************

	public void doRawFitness(Chromo X, Chromo[] members, int gen, int testSuiteGens, int strat){
		
		Strategy player;
		StrategyWeights2 playerW;
		Strategy player1;
		StrategyWeights2 playerW1;
		Strategy player2;
		Strategy player3;
		Strategy player4;
		Strategy player5;
		Strategy player6;
      	IteratedPD ipd;

		X.rawFitness = 0;

		switch (strat){
		case 1: player = new StrategyLookUpTable(); break;		
		default: player = new StrategySimple(); break;
		}
		player.getCurrLength(Parameters.geneSize);
		player.getCurrStrat(X.chromo);

		playerW = new StrategyWeights2();
		if(strat == 2){
			playerW.a = playerW.getCurrWeights(X.getIntGeneValue(0));
			playerW.b = playerW.getCurrWeights(X.getIntGeneValue(1));
			playerW.c = playerW.getCurrWeights(X.getIntGeneValue(2));
			playerW.d = playerW.getCurrWeights(X.getIntGeneValue(3));
			playerW.e = playerW.getCurrWeights(X.getIntGeneValue(4));
			playerW.f = playerW.getCurrWeights(X.getIntGeneValue(5));
			playerW.g = playerW.getCurrWeights(X.getIntGeneValue(6));
		}

		player2 = new StrategyAlwaysCooperate();	
		player3 = new StrategyRandom();
		player4 = new StrategyAlwaysDefect();
		player5 = new StrategyTitForTat();
		player6 = new StrategyTitForTwoTats();

		if (gen<testSuiteGens){
			if(strat == 2){
				ipd = new IteratedPD(playerW, player2);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(playerW, player3);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(playerW, player4);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(playerW, player5);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(playerW, player6);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				X.rawFitness /= 5;
			}
			else{
				ipd = new IteratedPD(player, player2);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(player, player3);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(player, player4);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(player, player5);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				ipd = new IteratedPD(player, player6);
				ipd.runSteps(Parameters.pdIterations);
				X.rawFitness += ipd.player1Score();
				X.rawFitness /= 5;
			}
		}
		else{
			int randChoice = 0;
			for(int i=0; i<5; i++){
				randChoice = Search.r.nextInt(members.length-1);
				switch (strat){
				case 1: player1 = new StrategyLookUpTable(); break;
				default: player1 = new StrategySimple(); break;
				}
				player1.getCurrLength(Parameters.geneSize);
				player1.getCurrStrat(members[randChoice].chromo);
				if(strat == 2){
					playerW1 = new StrategyWeights2();
					playerW1.a = playerW1.getCurrWeights(members[randChoice].getIntGeneValue(0));
					playerW1.b = playerW1.getCurrWeights(members[randChoice].getIntGeneValue(1));
					playerW1.c = playerW1.getCurrWeights(members[randChoice].getIntGeneValue(2));
					playerW1.d = playerW1.getCurrWeights(members[randChoice].getIntGeneValue(3));
					playerW1.e = playerW1.getCurrWeights(members[randChoice].getIntGeneValue(4));
					playerW1.f = playerW1.getCurrWeights(members[randChoice].getIntGeneValue(5));
					playerW1.g = playerW1.getCurrWeights(members[randChoice].getIntGeneValue(6));
					
					ipd = new IteratedPD(playerW, playerW1);
					ipd.runSteps(Parameters.pdIterations);
					X.rawFitness += ipd.player1Score();
				}
				else{
					ipd = new IteratedPD(player, player1);
					ipd.runSteps(Parameters.pdIterations);
					X.rawFitness += ipd.player1Score();
				}
			}
			
			X.rawFitness /= 5;
		}
	}

//  PRINT OUT AN INDIVIDUAL GENE TO THE SUMMARY FILE *********************************

	public void doPrintGenes(Chromo X, FileWriter output) throws java.io.IOException{

		for (int i=0; i<Parameters.numGenes; i++){
			Hwrite.right(X.getGeneAlpha(i),11,output);
		}
		output.write("   RawFitness");
		output.write("\n        ");
		for (int i=0; i<Parameters.numGenes; i++){
			Hwrite.right(X.getPosIntGeneValue(i),11,output);
		}
		Hwrite.right((int) X.rawFitness,13,output);
		output.write("\n\n");
		return;
	}

/*******************************************************************************
*                             STATIC METHODS                                   *
*******************************************************************************/

}   

